package com.deyuanyun.pic.ctrl.service.impl;


import java.util.Date;
import java.util.List;

import com.deyuanyun.pic.ctrl.domain.CtrlRepairTask;
import com.deyuanyun.pic.ctrl.mapper.CtrlRepairTaskMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.deyuanyun.pic.common.util.StringUtils;
import com.deyuanyun.pic.common.util.web.Asserts;
import com.deyuanyun.pic.ctrl.controller.dto.ExinspOclpointQueryVO;
import com.deyuanyun.pic.ctrl.controller.dto.ExinspOclpointDTO;
import com.deyuanyun.pic.ctrl.controller.dto.RepairTaskDTO;
import com.deyuanyun.pic.ctrl.controller.dto.RepairTaskQueryVO;
import com.deyuanyun.pic.ctrl.domain.ExinspOclpoint;
import com.deyuanyun.pic.ctrl.enumeration.DefectStateEnum;
import com.deyuanyun.pic.ctrl.enumeration.RepairStateEnum;
import com.deyuanyun.pic.ctrl.enumeration.RepairTaskStatedEnum;
import com.deyuanyun.pic.ctrl.mapper.ExinspOclpointMapper;
import com.deyuanyun.pic.ctrl.mapper.repair.CoatRepairTaskExpandMapper;
import com.deyuanyun.pic.ctrl.service.CoatRepairTaskService;
import com.deyuanyun.pic.settings.controller.dto.UserSessionVO;
import com.deyuanyun.pic.settings.controller.pipe.vo.PipeLocationDTO;
import com.deyuanyun.pic.settings.domain.util.DomainInitUtil;
import com.deyuanyun.pic.settings.service.msgtemplate.PushMessage;
import com.deyuanyun.pic.settings.service.pipe.PipeLocationService;
import com.deyuanyun.pic.settings.support.cache.SessionCacheSupport;

@Service
public class CoatRepairTaskServiceImpl implements CoatRepairTaskService {
    
    private @Autowired CtrlRepairTaskMapper repairTaskMapper;
    private @Autowired ExinspOclpointMapper defectInfoMapper;
    private @Autowired CoatRepairTaskExpandMapper repairTaskExpandMapper;
    private @Autowired PipeLocationService pipeLocationService;
    
    
    //private @Autowired InsspSegmentMapper insspSegmentMapper;//检测管段的
    //private @Autowired DefectInfoService defectInfoService;//缺陷点信息Service
    
    private static final Logger logger = LoggerFactory.getLogger(CoatRepairTaskServiceImpl.class);

    @Override
    public List<RepairTaskDTO> queryRepairTaskList(RepairTaskQueryVO repairTaskVO){
        
        List<RepairTaskDTO> repairTaskList = repairTaskExpandMapper.queryRepairTaskList(repairTaskVO);
        
        return repairTaskList;
    }

    @Override
    public List<ExinspOclpointDTO> queryDefectInfoList(String[] repairTaskId){
        return queryDefectInfoList(repairTaskId,null);
    }
    

    @Override
    public List<ExinspOclpointDTO> queryDefectInfoList(String[] repairTaskId,RepairStateEnum[] repairStateds){
        ExinspOclpointQueryVO defectSuggest = new ExinspOclpointQueryVO();
        defectSuggest.setRepairTaskIds(repairTaskId);
        defectSuggest.setRepairStateds(repairStateds);
        
        List<ExinspOclpointDTO> defectInfoList = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        
        return defectInfoList;
    }
    
    //填充起止点名称和绝对距离
    private void fillRepairTaskPointNameAndMileage(CtrlRepairTask repairTask){
        
        String fromPointId = repairTask.getFromPointId();
        String endPointId = repairTask.getToPointId();
        String pipeLineId = repairTask.getPipeLineId();
        
        PipeLocationDTO pipeLocation1 = pipeLocationService.queryPipeLocationById(pipeLineId,fromPointId);
        repairTask.setFromPointMileage(pipeLocation1.getMileage2());
        
        PipeLocationDTO pipeLocation2 = pipeLocationService.queryPipeLocationById(pipeLineId,endPointId);
        repairTask.setToPointMileage(pipeLocation2.getMileage2());
    }
    
    
    
    @Override
    @PushMessage
    public void createOrUpdate(CtrlRepairTask repairTask, String[] defectInfoIds) {
        Asserts.assertTrue(defectInfoIds.length != 0, "需选择添加漏损点！");
        String rtId = repairTask.getId();
        if(StringUtils.isEmpty(rtId)){
            repairTask.setRepairState(RepairTaskStatedEnum.WAIT_FOR_REPAIR.toString());//默认情况下新增进来就是待修复
            DomainInitUtil.initCreateDomain(repairTask);
            rtId = repairTask.getId();
            String dataStated = repairTask.getDataStated();
            if("20".equals(dataStated)){//如果是直接保存为已发布，保存时间也保存进去。
                UserSessionVO sessionVO= SessionCacheSupport.getSessionVO();
                String user = sessionVO.getUsername();
                repairTask.setReleaseUser(user);
                repairTask.setReleaseDate(new Date());
            }
            fillRepairTaskPointNameAndMileage(repairTask);//填充起止点名称和绝对距离
            
            logger.debug("创建维修任务RepairTask>" + rtId);
            repairTaskMapper.insertSelective(repairTask);
            //
            
        }else{
            //判断一下，如果是已发布任务不能修改。
            CtrlRepairTask repairTask_Old = selectByPrimaryKey(rtId);
            if(repairTask_Old != null){
                Asserts.assertTrue(!DefectStateEnum.state20.getCode().equals(repairTask_Old.getDataStated()), "已发布任务不能再次修改");
            }
            fillRepairTaskPointNameAndMileage(repairTask);//填充起止点名称和绝对距离
            logger.debug("更新维修任务RepairTask>" + rtId);
            DomainInitUtil.initUpdateDomain(repairTask);
            repairTaskMapper.updateByPrimaryKeySelective(repairTask);
            
            //修改维修任务时，把原有的缺陷点全部去掉。
            repairTaskExpandMapper.updateDefectInfoRepairTaskIdToNull(rtId);
        }
        
        //判断缺陷点是否已被加入了别的维修任务
        ExinspOclpointQueryVO defectSuggest = new ExinspOclpointQueryVO();
        defectSuggest.setDefectInfoId(defectInfoIds);
        //defectSuggest.setRepairTaskIdIsNull(true);
        List<ExinspOclpointDTO> defectInfoList = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        for (int i = 0; i < defectInfoList.size(); i++) {
            ExinspOclpointDTO exinspOclpoint = defectInfoList.get(i);
            String customNumber = exinspOclpoint.getCustomNumber();
            String repairTaskId = exinspOclpoint.getRepairTaskId();
            Asserts.assertTrue(StringUtils.isEmpty(repairTaskId) || rtId.equals(repairTaskId), customNumber + "已被加入了别的维修任务。");
        }
        //Asserts.assertTrue(defectInfoIds.length == defectInfoList.size(), "有缺陷点已被加入了别的维修任务。");
        
        for (int i = 0; i < defectInfoIds.length; i++) {
            String defectInfoId = defectInfoIds[i];
            ExinspOclpoint defectInfo = new ExinspOclpoint();
            defectInfo.setId(defectInfoId);
            defectInfo.setRepairTaskId(rtId);
            defectInfo.setRepairState(RepairStateEnum.WAIT_FOR_REPAIR.toString());//把缺陷点状态置为待维修
            DomainInitUtil.initUpdateDomain(defectInfo,"指定维修任务>" + rtId);
            logger.debug("指定维修任务 " + defectInfoId + ">" + rtId);
            defectInfoMapper.updateByPrimaryKeySelective(defectInfo);
        }
    }

    
    @Override
    @PushMessage
    public int updateDataStated(String[] rtIds,DefectStateEnum dataStated) {
        int succ = 0;
        for (int i = 0; i < rtIds.length; i++) {
            String rtId = rtIds[i];

            CtrlRepairTask repairTask_Old = selectByPrimaryKey(rtId);
            if(repairTask_Old == null){
                continue;
            }

            CtrlRepairTask repairTask = new CtrlRepairTask();
            repairTask.setId(rtId);
            
            if(DefectStateEnum.state20 == dataStated ){
                //需要发布这个任务
                if(!DefectStateEnum.state01.getCode().equals(repairTask_Old.getDataStated())){
                    //这个任务不是属于待发布
                    logger.debug("只有待发布的任务才能发布>" + rtId);
                    continue;
                }else{
                    UserSessionVO sessionVO= SessionCacheSupport.getSessionVO();
                    String user = sessionVO.getUsername();
                    repairTask.setReleaseUser(user);
                    repairTask.setReleaseDate(new Date());
                }
            }
            
            repairTask.setDataStated(dataStated.getCode());
            DomainInitUtil.initUpdateDomain(repairTask,"更改状态>" + dataStated.getValue());
            succ += updateByPrimaryKeySelective(repairTask);
        }
        return succ;
        
    }

    
    @Override
    @PushMessage
    public int updateRepairTaskStated(String[] rtIds, RepairTaskStatedEnum repairTaskStated) {
        int succ = 0;
        for (int i = 0; i < rtIds.length; i++) {
            String rtId = rtIds[i];
            
            if(RepairTaskStatedEnum.ALREADY_REPAIR == repairTaskStated){
                //判断任务是否已经完成
                CtrlRepairTask repairTask_T = repairTaskMapper.selectByPrimaryKey(rtId);
                if(repairTask_T == null
                        || RepairTaskStatedEnum.ALREADY_REPAIR.toString().equals(repairTask_T.getRepairState())){
                    logger.info("已关闭任务不能再次关闭、" + rtId + "、" + repairTask_T);
                    continue;
                }
                
                //只查询维护中和待修复的缺陷点
                RepairStateEnum[] repairStateds = {RepairStateEnum.WAIT_FOR_REPAIR,RepairStateEnum.MAINTENANCE};
                List<ExinspOclpointDTO> defectInfoList = queryDefectInfoList(new String[]{rtId}, repairStateds);
                if(defectInfoList != null && !defectInfoList.isEmpty()){
                    logger.debug("只有全部维修结束（维修完成或者难以维修）状态的任务才能关闭>" + rtId);
                    continue;
                }
            }

            CtrlRepairTask repairTask = new CtrlRepairTask();
            repairTask.setId(rtId);
            repairTask.setRepairState(repairTaskStated.toString());
            DomainInitUtil.initUpdateDomain(repairTask,"更改维修状态>" + repairTaskStated.getLabel());
            succ += updateByPrimaryKeySelective(repairTask);
        }
        return succ;
    }

    @Override
    public int updateToDelete(String[] rtIds) {
        int secc = 0;//返回成功数量
        for (int i = 0; i < rtIds.length; i++) {
            String rtId = rtIds[i];

            CtrlRepairTask repairTask_Old = selectByPrimaryKey(rtId);
            if(repairTask_Old == null){
                continue;
            }
            if(DefectStateEnum.state20.getCode().equals(repairTask_Old.getDataStated())){
                logger.debug("已发布的维修任务不能删除>" + rtId);
                continue;
            }

            CtrlRepairTask repairTask = new CtrlRepairTask();
            repairTask.setId(rtId);
            repairTask.setDeleted((short)1);
            DomainInitUtil.initUpdateDomain(repairTask,"删除任务");
            secc += updateByPrimaryKeySelective(repairTask);
            //TODO 待处理：删除维修任务的时候，缺陷点的WAIT_FOR_REPAIR应当置为NULL
            //清除pic_tdf_defect_info表中的REPAIR_TASK_ID置为NULL.....
            repairTaskExpandMapper.updateDefectInfoRepairTaskIdToNull(rtId);
        }
        return secc;
    }

    /*
    @Override
    public RepairTaskWorkload queryRepairTaskWorkload(String repairTaskId) {
        
        RepairTaskWorkloadExample example = new RepairTaskWorkloadExample();
        example.createCriteria().andRepairTaskIdEqualTo(repairTaskId);
        
        List<RepairTaskWorkload> repairTaskWorkloadList = repairTaskWorkloadMapper.selectByExample(example);
        if(repairTaskWorkloadList != null && !repairTaskWorkloadList.isEmpty()){
            return repairTaskWorkloadList.get(0);
        }
        
        return null;
    }

    @Cacheable(value = "tempStoreData")
    @Override
    public Map<String, Object> queryInspSegmentByName(String pipeName,String inspSegmentName) {
        
        InspSegmentInfraVO inspSegmentInfra = new InspSegmentInfraVO();
        inspSegmentInfra.setLineName(pipeName);
        inspSegmentInfra.setInspSegmentName(inspSegmentName);
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> list = insspSegmentMapper.inspFindByCondition(inspSegmentInfra);
        if(list == null || list.isEmpty()){
            return null;
        }
        return list.get(0);
    }
*/    
    
    
    @Override
    public ExinspOclpointDTO queryDefectInfoByCustomNumber(String customNumbers) {
        
        ExinspOclpointQueryVO defectSuggest = new ExinspOclpointQueryVO();
        defectSuggest.setCustomNumbers(new String[]{customNumbers});
        
        List<ExinspOclpointDTO> defectInfoList = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        if(defectInfoList == null || defectInfoList.isEmpty()){
            return null;
        }
        return defectInfoList.get(0);
    }
    
    @Override
    public List<ExinspOclpointDTO> queryDefectInfoByCustomNumber(String[] customNumbers){

        ExinspOclpointQueryVO defectSuggest = new ExinspOclpointQueryVO();
        defectSuggest.setCustomNumbers(customNumbers);
        
        List<ExinspOclpointDTO> defectInfoList = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        if(defectInfoList == null || defectInfoList.isEmpty()){
            return null;
        }
        return defectInfoList;
    }
    
    @Override
    public ExinspOclpointDTO queryExinspOclpointDTO(String defectInfoId){

        ExinspOclpointQueryVO defectSuggest = new ExinspOclpointQueryVO();
        defectSuggest.setDefectInfoId(new String[]{defectInfoId});
        
        List<ExinspOclpointDTO> defectInfoList = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        if(defectInfoList == null || defectInfoList.isEmpty()){
            return null;
        }
        return defectInfoList.get(0);
    }
    
    @Override
    public List<ExinspOclpointDTO> queryExinspOclpoint(ExinspOclpointQueryVO defectSuggest) {
        List<ExinspOclpointDTO> list = repairTaskExpandMapper.queryExinspOclpoint(defectSuggest);
        return list;
    }

    public CtrlRepairTask selectByPrimaryKey(String id) {
        return this.repairTaskMapper.selectByPrimaryKey(id);
    }

    public int deleteByPrimaryKey(String id) {
        return this.repairTaskMapper.deleteByPrimaryKey(id);
    }

    public int updateByPrimaryKeySelective(CtrlRepairTask record) {
        return this.repairTaskMapper.updateByPrimaryKeySelective(record);
    }

    public int updateByPrimaryKey(CtrlRepairTask record) {
        return this.repairTaskMapper.updateByPrimaryKey(record);
    }

    public int insert(CtrlRepairTask record) {
        return this.repairTaskMapper.insert(record);
    }
}